Connectivity Software User's Guide and Reference
Data Notifications in Sparkplug Consumer
Rapid Toolkit for Sparkplug > Concepts > Developing Sparkplug Host Applications > Data Notifications in Sparkplug Consumer
In This Topic

Introduction

As described in Subscribing to Data in Sparkplug Consumer, when you make a method call on the consumer object to subscribe to Sparkplug data, the data and status information come back in form of data notifications (events and/or callbacks).

This article describes the contents of the data notifications, their types, and how to process them.

Notification Contents

Each data notification carries with it an event arguments objects. There is a separate type of the event arguments for metric notifications and payload notifications, but they both derive from the EasySparkplugNotificationEventArgs Class. This class contains members that are common to both metric and payload data notifications. The most important members are listed below.

The strings in the Sparkplug IDs (GroupId PropertyEdgeNodeId Property, and DeviceId Property) have wildcards resolved, when possible. This means that if you have used a filter (such as "#") to specify the ID in the subscription, the value in the corresponding property will not contain the filter you specified, but rather the actual, concrete ID of the group, edge node or device to which the data notification carries the information. The Connect and Disconnect notification types, however, cannot be related to a specific Sparkplug component, and for them the properties contain the filter you have specified in the subscription. 

Notification Types

The type of the data notification is contain in the NotificationType Property of the notitication event arguments, which can contain values from the SparkplugNotificationType Enumeration:

All subscriptions start in the disconnected state. It attempts to connect then (or it can reuse an existing connection). If the connection cannot be made, you will receive a Disconnect data notification, or even more of them if the problemn persists, over time. If/when the connection eventually succeeds, you will receive a Connect data notification. Only then the Birth, Data, and Death data notifications can follow. Eventually, the subscription is terminated with the Disconnect data notification.

Only the Birth and Data notifications contain the actual metric or payload. The remaining notifications are for status information.

Synthesized Messages

In Sparkplug, the edge node or device announces its metrics and their metadata using the Birth message. The information contained in the Birth message is crucial for proper interpretation and processing of the Data messages that follow. It is, however, perfectly possible that a consumer (Sparkplug host applications) starts and/or wants to subscribe after the edge node or device has already sent the Birth message (this happens especially when the edge node is not configured with the primary host application ID). In such case, Rapid Toolkit for Sparkplug automatically issues a "request rebirth" command to the edge node or device, so that it resends the Birth message and the consumer can process it.

In other cases, your code can be making a subscription, and Rapid Toolkit for Sparkplug already has enough information about the metrics and metadata - possibly because it has received the Birth message before. In such case, Rapid Toolkit for Sparkplug will simply reuse the information it already has, and synthesize the Birth message as if it was just produced. This way, your code can expect that the order of the incoming notifications will be Birth - Data - Data - Data - .... - Death (keeping in mind that Disconnect and Connect notifications can interrupt the sequence).

Whether or not the particular notification has been synthesized is indicated by the IsSynthesized Property available in the event arguments of the notification.

Metric Notification

When you make a subscription using any of the methods described under Subscribing to Metrics in Subscribing to Data in Sparkplug Consumer, the data notifications will be delivered to you using the MetricNotification Event on the consumer object (and, optionally, using a callback - see further down in this article). The metric data notification carries with it an instance of the EasySparkplugMetricNotificationEventArgs Class. In addition to the members common to all data notifications (described earlier in this article), this object provides

The metric name has wildcards resolved, when possible, i.e. if you have used a filter (such as "#") to specify the metric name in the subscription, the MetricName Property does not contain the filter you specified, but rather the actual, concrete name of the metric to which the data notification carries the information. The Connect and Disconnect notification types, however, cannot be related to a specific Sparkplug component, and for them the property contains the filter you have specified in the subscription.

In Sparkplug, metadata is normally provided in the Birth messages only. Rapid Toolkit for Sparkplug, however, replicates the metadata from the Birth message into the subsequent Data notifications for the same metric, so that your code does not have to store the Birth notifications and correlate them with the Data notifications.

The following example illustrates processing of a metric notification.

.NET

// This example shows how to subscribe to all metrics of a given edge node and display the name and value of the metric with
// each notification.
//
// In order to publish or observe messages for this example, start the SparkplugEdgeNodeConsoleDemo program first.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-ConnectivityStudio/Latest/examples.html .
// Sparkplug examples in C# on GitHub: https://github.com/OPCLabs/Examples-ConnectivityStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasySparkplug;
using OpcLabs.EasySparkplug.OperationModel;

namespace SparkplugDocExamples.Consumer._EasySparkplugConsumer
{
    partial class SubscribeEdgeNodeMetric
    {
        public static void Overload1()
        {
            // Note that the default port for the "mqtt" scheme is 1883.
            var hostDescriptor = new SparkplugHostDescriptor("mqtt://localhost");

            // Instantiate the consumer object and hook events.
            var consumer = new EasySparkplugConsumer();
            consumer.MetricNotification += consumer_Overload1_MetricNotification;

            Console.WriteLine("Subscribing...");
            // In this example, we specify the precise Sparkplug group ID and edge node ID, but allow any metric name.
            consumer.SubscribeEdgeNodeMetric(hostDescriptor, 
                "easyGroup", "easySparkplugDemo", "#");

            Console.WriteLine("Processing notifications for 20 seconds...");
            System.Threading.Thread.Sleep(20 * 1000);

            Console.WriteLine("Unsubscribing...");
            consumer.UnsubscribeAllMetrics();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }


        static void consumer_Overload1_MetricNotification(object sender, EasySparkplugMetricNotificationEventArgs eventArgs)
        {
            // Handle different types of notifications.
            Console.WriteLine();
            switch (eventArgs.NotificationType)
            {
                case SparkplugNotificationType.Connect:
                    Console.WriteLine($"Connected to Sparkplug host, client ID: {eventArgs.ClientId}.");
                    break;
                case SparkplugNotificationType.Disconnect:
                    Console.WriteLine("Disconnected from Sparkplug host.");
                    break;
                case SparkplugNotificationType.Data:
                    Console.WriteLine("Received data from Sparkplug host.");
                    Console.WriteLine($"Metric name: {eventArgs.MetricName}");
                    Console.WriteLine($"Value: {eventArgs.MetricData?.Value}");
                    break;
                case SparkplugNotificationType.Birth:
                    Console.WriteLine("Received birth message from Sparkplug host.");
                    Console.WriteLine($"Metric name: {eventArgs.MetricName}");
                    Console.WriteLine($"Value: {eventArgs.MetricData?.Value}");
                    break;
                case SparkplugNotificationType.Death:
                    Console.WriteLine("Received death message from Sparkplug host.");
                    Console.WriteLine($"Metric name: {eventArgs.MetricName}");
                    break;
            }
            if (!eventArgs.Succeeded)
                Console.WriteLine($"*** Failure: {eventArgs.ErrorMessageBrief}");
        }
    }
}
' This example shows how to subscribe to all metrics of a given edge node and display the name and value of the metric with
' each notification.
'
' In order to publish or observe messages for this example, start the SparkplugEdgeNodeConsoleDemo program first.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-ConnectivityStudio/Latest/examples.html .
' Sparkplug examples in C# on GitHub: https://github.com/OPCLabs/Examples-ConnectivityStudio-CSharp .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasySparkplug
Imports OpcLabs.EasySparkplug.OperationModel

Namespace Global.SparkplugDocExamples.Consumer._EasySparkplugConsumer
    Partial Class SubscribeEdgeNodeMetric
        Public Shared Sub Overload1()
            ' Note that the default port for the "mqtt" scheme is 1883.
            Dim hostDescriptor = New SparkplugHostDescriptor("mqtt://localhost")

            ' Instantiate the consumer object and hook events.
            Dim consumer = New EasySparkplugConsumer()
            AddHandler consumer.MetricNotification, AddressOf consumer_Overload1_MetricNotification

            Console.WriteLine("Subscribing...")
            ' In this example, we specify the precise Sparkplug group ID and edge node ID, but allow any metric name.
            consumer.SubscribeEdgeNodeMetric(hostDescriptor,
                "easyGroup", "easySparkplugDemo", "#")

            Console.WriteLine("Processing notifications for 20 seconds...")
            Threading.Thread.Sleep(20 * 1000)

            Console.WriteLine("Unsubscribing...")
            consumer.UnsubscribeAllMetrics()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)

            Console.WriteLine("Finished.")
        End Sub

        Private Shared Sub consumer_Overload1_MetricNotification(ByVal sender As Object, ByVal eventArgs As EasySparkplugMetricNotificationEventArgs)
            ' Handle different types of notifications.
            Console.WriteLine()
            Select Case eventArgs.NotificationType
                Case SparkplugNotificationType.Connect
                    Console.WriteLine($"Connected to Sparkplug host, client ID: {eventArgs.ClientId}.")
                Case SparkplugNotificationType.Disconnect
                    Console.WriteLine("Disconnected from Sparkplug host.")
                Case SparkplugNotificationType.Data
                    Console.WriteLine("Received data from Sparkplug host.")
                    Console.WriteLine($"Metric name: {eventArgs.MetricName}")
                    Console.WriteLine($"Value: {eventArgs.MetricData?.Value}")
                Case SparkplugNotificationType.Birth
                    Console.WriteLine("Received birth message from Sparkplug host.")
                    Console.WriteLine($"Metric name: {eventArgs.MetricName}")
                    Console.WriteLine($"Value: {eventArgs.MetricData?.Value}")
                Case SparkplugNotificationType.Death
                    Console.WriteLine("Received death message from Sparkplug host.")
                    Console.WriteLine($"Metric name: {eventArgs.MetricName}")
            End Select
            If Not eventArgs.Succeeded Then
                Console.WriteLine($"*** Failure: {eventArgs.ErrorMessageBrief}")
            End If
        End Sub
    End Class
End Namespace

 

Payload Notification

When you make a subscription using any of the methods described under Subscribing to Payloads in Subscribing to Data in Sparkplug Consumer, the data notifications will be delivered to you using the PayloadNotification Event on the consumer object (and, optionally, using a callback - see further down in this article). The payload data notification carries with it an instance of the EasySparkplugPayloadNotificationEventArgs Class. In addition to the members common to all data notifications (described earlier in this article), this object provides

The payload is an instance of the SparkplugPayload Class, and it acts as a collection of payload elements. Each payload element is key-value pair, where the key is the name of the metric, and the value is an instance of the SparkplugMetricElement Class, containing the metric data, and optionally a metadata for the same metric. Alternatively, the information in the payload can be accessed through dictionaries, keyed by the metric name. For metrics contained in the payload, the MetricDataDictionary Property contains a read-only dictionary of Sparkplug metric data, and the MetadataDictionary Property contains a read-only dictionary of Sparkplug metadata for the same metrics (or their subset, as the metadata is optional).

Note that in Sparkplug, metadata is normally provided in the Birth messages only. Rapid Toolkit for Sparkplug, however, replicates the metadata from the Birth message into the subsequent Data notifications for the same metric, so that your code does not have to store the Birth notifications and correlate them with the Data notifications.

The following example illustrates processing of a payload notification.

.NET

// This example shows how to subscribe to the payload with all metrics of a given edge node and display the received payload
// with each notification.
//
// In order to publish or observe messages for this example, start the SparkplugEdgeNodeConsoleDemo program first.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-ConnectivityStudio/Latest/examples.html .
// Sparkplug examples in C# on GitHub: https://github.com/OPCLabs/Examples-ConnectivityStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using System.Collections.Generic;
using OpcLabs.EasySparkplug;
using OpcLabs.EasySparkplug.OperationModel;

namespace SparkplugDocExamples.Consumer._EasySparkplugConsumer
{
    class SubscribeEdgeNodePayload
    {
        public static void Overload1()
        {
            // Note that the default port for the "mqtt" scheme is 1883.
            var hostDescriptor = new SparkplugHostDescriptor("mqtt://localhost");

            // Instantiate the consumer object and hook events.
            var consumer = new EasySparkplugConsumer();
            consumer.PayloadNotification += consumer_Overload1_PayloadNotification;

            Console.WriteLine("Subscribing...");
            consumer.SubscribeEdgeNodePayload(hostDescriptor, "easyGroup", "easySparkplugDemo");

            Console.WriteLine("Processing notifications for 20 seconds...");
            System.Threading.Thread.Sleep(20 * 1000);

            Console.WriteLine("Unsubscribing...");
            consumer.UnsubscribeAllPayloads();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }


        static void consumer_Overload1_PayloadNotification(object sender, EasySparkplugPayloadNotificationEventArgs eventArgs)
        {
            // Handle different types of notifications.
            Console.WriteLine();
            switch (eventArgs.NotificationType)
            {
                case SparkplugNotificationType.Connect:
                    Console.WriteLine($"Connected to Sparkplug host, client ID: {eventArgs.ClientId}.");
                    break;
                case SparkplugNotificationType.Disconnect:
                    Console.WriteLine("Disconnected from Sparkplug host.");
                    break;
                case SparkplugNotificationType.Data:
                case SparkplugNotificationType.Birth:
                    Console.WriteLine("Received birth or data message from Sparkplug host.");
                    // Display the metrics name and data for each metric delivered in the payload.
                    foreach (KeyValuePair<string, SparkplugMetricElement> pair in eventArgs.Payload)
                        Console.WriteLine($"{pair.Key}: {pair.Value.MetricData}");
                    break;
                case SparkplugNotificationType.Death:
                    Console.WriteLine("Received death message from Sparkplug host.");
                    break;
            }
            if (!eventArgs.Succeeded)
                Console.WriteLine($"*** Failure: {eventArgs.ErrorMessageBrief}");
        }
    }
}
' This example shows how to subscribe to the payload with all metrics of a given edge node and display the received payload
' with each notification.
'
' In order to publish or observe messages for this example, start the SparkplugEdgeNodeConsoleDemo program first.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-ConnectivityStudio/Latest/examples.html .
' Sparkplug examples in C# on GitHub: https://github.com/OPCLabs/Examples-ConnectivityStudio-CSharp .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasySparkplug
Imports OpcLabs.EasySparkplug.OperationModel

Namespace Global.SparkplugDocExamples.Consumer._EasySparkplugConsumer
    Class SubscribeEdgeNodePayload
        Public Shared Sub Overload1()
            ' Note that the default port for the "mqtt" scheme is 1883.
            Dim hostDescriptor = New SparkplugHostDescriptor("mqtt://localhost")

            ' Instantiate the consumer object and hook events.
            Dim consumer = New EasySparkplugConsumer()
            AddHandler consumer.PayloadNotification, AddressOf consumer_Overload1_PayloadNotification

            Console.WriteLine("Subscribing...")
            consumer.SubscribeEdgeNodePayload(hostDescriptor, "easyGroup", "easySparkplugDemo")

            Console.WriteLine("Processing notifications for 20 seconds...")
            Threading.Thread.Sleep(20 * 1000)

            Console.WriteLine("Unsubscribing...")
            consumer.UnsubscribeAllPayloads()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)

            Console.WriteLine("Finished.")
        End Sub

        Private Shared Sub consumer_Overload1_PayloadNotification(ByVal sender As Object, ByVal eventArgs As EasySparkplugPayloadNotificationEventArgs)
            ' Handle different types of notifications.
            Console.WriteLine()
            Select Case eventArgs.NotificationType
                Case SparkplugNotificationType.Connect
                    Console.WriteLine($"Connected to Sparkplug host, client ID: {eventArgs.ClientId}.")
                Case SparkplugNotificationType.Disconnect
                    Console.WriteLine("Disconnected from Sparkplug host.")
                Case SparkplugNotificationType.Data,
                    SparkplugNotificationType.Birth
                    Console.WriteLine("Received birth or data message from Sparkplug host.")
                    ' Display the metrics name and data for each metric delivered in the payload.
                    For Each pair As KeyValuePair(Of String, SparkplugMetricElement) In eventArgs.Payload
                        Console.WriteLine($"{pair.Key}: {pair.Value.MetricData}")
                    Next
                Case SparkplugNotificationType.Death
                    Console.WriteLine("Received death message from Sparkplug host.")
            End Select
            If Not eventArgs.Succeeded Then
                Console.WriteLine($"*** Failure: {eventArgs.ErrorMessageBrief}")
            End If
        End Sub
    End Class
End Namespace

 

Using Callbacks

Data notifications originating in the consumer object are always delivered as events. In addition, when making the subscription, you can also specify a callback. The callback is a method that will be called (in addition to raising the event) for each data notification for the subscription you are making. There are some differences between the events and callbacks (such as that the events are common for all subscritpions on the consumer object), but in general, both approaches can do the job. Whether you use the events, or callbacks, is largely a decision that depends on the code clarity in your particular case, and perhaps even your personal coding preferences.

Generally, the callback is specified using a property in the argument object passed to the subscription method. It is the EasySparkplugMetricSubscriptionArguments.Callback Property when subscribing to metrics, or the EasySparkplugPayloadSubscriptionArguments.Callback Property when subscribing to payloads. By default, this property is null, and no callback takes place (onlyan event is raised). When this property is set to a non-null method reference, the method is called for data notifications from the subscription, in addition to raising the event.

Usually, you do not assemble the argument object passed to the subscription method in your code. There are various overloads and extension method for making the subscriptions, and may of them include the callback as a separate argument. This way, you can simply specify the callback method as one of the arguments to the subscription method call. The necessary argument object, and filling in of the Callback property, happens behind the scenes for you.

The following example illustrates how a lambda method can be used as a callback for data notifications from edge node metrics.

.NET

// This example shows how to subscribe to changes of a single metric, and display the value of the metric with each change
// using a callback method that is provided as lambda expression.
//
// In order to publish or observe messages for this example, start the SparkplugEdgeNodeConsoleDemo program first.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-ConnectivityStudio/Latest/examples.html .
// Sparkplug examples in C# on GitHub: https://github.com/OPCLabs/Examples-ConnectivityStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using OpcLabs.EasySparkplug;
using System;

namespace SparkplugDocExamples.Consumer._EasySparkplugConsumer
{
    partial class SubscribeEdgeNodeMetric
    {
        public static void CallbackLambda()
        {
            // Note that the default port for the "mqtt" scheme is 1883.
            var hostDescriptor = new SparkplugHostDescriptor("mqtt://localhost");

            // Instantiate the consumer object.
            var consumer = new EasySparkplugConsumer();

            Console.WriteLine("Subscribing...");
            // The callback is a lambda expression the displays the value
            // In this example, we specify the precise Sparkplug group ID, edge node ID, and metric name.
            consumer.SubscribeEdgeNodeMetric(hostDescriptor, 
                "easyGroup", "easySparkplugDemo", "Random",
                (sender, eventArgs) =>
                {
                    if (eventArgs.Succeeded)
                    {
                        if (eventArgs.HasData)
                            Console.WriteLine("Value: {0}", eventArgs.MetricData?.Value);
                    }
                    else
                        Console.WriteLine("*** Failure: {0}", eventArgs.ErrorMessageBrief);
                });

            Console.WriteLine("Processing notifications for 20 seconds...");
            System.Threading.Thread.Sleep(20 * 1000);

            Console.WriteLine("Unsubscribing...");
            consumer.UnsubscribeAllMetrics();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }
    }
}
' This example shows how to subscribe to changes of a single metric, and display the value of the metric with each change
' using a callback method that is provided as lambda expression.
'
' In order to publish or observe messages for this example, start the SparkplugEdgeNodeConsoleDemo program first.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-ConnectivityStudio/Latest/examples.html .
' Sparkplug examples in C# on GitHub: https://github.com/OPCLabs/Examples-ConnectivityStudio-CSharp .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasySparkplug

Namespace Global.SparkplugDocExamples.Consumer._EasySparkplugConsumer
    Partial Class SubscribeEdgeNodeMetric
        Public Shared Sub CallbackLambda()
            ' Note that the default port for the "mqtt" scheme is 1883.
            Dim hostDescriptor = New SparkplugHostDescriptor("mqtt://localhost")

            ' Instantiate the consumer object.
            Dim consumer = New EasySparkplugConsumer()

            Console.WriteLine("Subscribing...")
            ' The callback is a lambda expression the displays the value
            ' In this example, we specify the precise Sparkplug group ID, edge node ID, and metric name.

            consumer.SubscribeEdgeNodeMetric(hostDescriptor,
                "easyGroup", "easySparkplugDemo", "Random",
                Sub(sender, eventArgs)
                    If (eventArgs.Succeeded) Then
                        If (eventArgs.HasData) Then
                            Console.WriteLine("Value: {0}", eventArgs.MetricData?.Value)
                        End If
                    Else
                        Console.WriteLine("*** Failure: {0}", eventArgs.ErrorMessageBrief)
                    End If
                End Sub)

            Console.WriteLine("Processing notifications for 20 seconds...")
            Threading.Thread.Sleep(20 * 1000)

            Console.WriteLine("Unsubscribing...")
            consumer.UnsubscribeAllMetrics()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)

            Console.WriteLine("Finished.")
        End Sub
    End Class
End Namespace

 

Identifying Subscriptions

If you make multiple subscriptions on the same consumer object, you may have a need to distinguish in the incoming notifications where they came from (which subscription has caused them). There are several ways to achieve it:

The following example illustrates how to subscribe to Sparkplug metrics, and identify the subscriptions using an integer value.

.NET

// This example shows how to subscribe to changes of multiple metrics and display each change, identifying the different
// subscriptions by an integer.
//
// In order to publish or observe messages for this example, start the SparkplugEdgeNodeConsoleDemo program first.
//
// Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-ConnectivityStudio/Latest/examples.html .
// Sparkplug examples in C# on GitHub: https://github.com/OPCLabs/Examples-ConnectivityStudio-CSharp .
// Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
// a commercial license in order to use Online Forums, and we reply to every post.

using System;
using OpcLabs.EasySparkplug;
using OpcLabs.EasySparkplug.OperationModel;

namespace SparkplugDocExamples.Consumer._EasySparkplugConsumer
{
    class SubscribeMetric
    {
        public static void StateAsInteger()
        {
            // Note that the default port for the "mqtt" scheme is 1883.
            var hostDescriptor = new SparkplugHostDescriptor("mqtt://localhost");

            // Instantiate the consumer object and hook events.
            var consumer = new EasySparkplugConsumer();
            consumer.MetricNotification += consumer_StateAsInteger_MetricNotification;

            Console.WriteLine("Subscribing...");
            consumer.SubscribeMetric(
                new EasySparkplugMetricSubscriptionArguments(SparkplugComponentTypes.EdgeNode, hostDescriptor, 
                    "easyGroup", "easySparkplugDemo", "", "Random", null)
                    { State = 1 });    // An integer we have chosen to identify the subscription
            consumer.SubscribeMetric(
                new EasySparkplugMetricSubscriptionArguments(SparkplugComponentTypes.EdgeNode, hostDescriptor,
                        "easyGroup", "easySparkplugDemo", "", "Simple", null)
                    { State = 2 });    // An integer we have chosen to identify the subscription
            consumer.SubscribeMetric(
                new EasySparkplugMetricSubscriptionArguments(SparkplugComponentTypes.EdgeNode, hostDescriptor,
                        "easyGroup", "easySparkplugDemo", "", "Ramp", null)
                    { State = 3 });    // An integer we have chosen to identify the subscription

            Console.WriteLine("Processing notifications for 20 seconds...");
            System.Threading.Thread.Sleep(20 * 1000);

            Console.WriteLine("Unsubscribing...");
            consumer.UnsubscribeAllMetrics();

            Console.WriteLine("Waiting for 5 seconds...");
            System.Threading.Thread.Sleep(5 * 1000);

            Console.WriteLine("Finished.");
        }


        static void consumer_StateAsInteger_MetricNotification(object sender, EasySparkplugMetricNotificationEventArgs eventArgs)
        {
            // Obtain the integer state we have passed in.
            // Note that the metric name also comes with the notification and can be used to determine which metric the
            // notification relates to. The reason we are using the state is that it allows to pass in the information that
            // your application understands immediately, and is thus more efficient.
            var stateAsInteger = (int)eventArgs.Arguments.State;

            // Display the data.
            if (eventArgs.Succeeded)
            {
                if (eventArgs.HasData)
                    Console.WriteLine($"{stateAsInteger}: {eventArgs.MetricData}");
            }
            else
                Console.WriteLine($"{stateAsInteger} *** Failure: {eventArgs.ErrorMessageBrief}");
        }
    }
}
' This example shows how to subscribe to changes of multiple metrics and display each change, identifying the different
' subscriptions by an integer.
'
' In order to publish or observe messages for this example, start the SparkplugEdgeNodeConsoleDemo program first.
'
' Find all latest examples here: https://opclabs.doc-that.com/files/onlinedocs/OPCLabs-ConnectivityStudio/Latest/examples.html .
' Sparkplug examples in C# on GitHub: https://github.com/OPCLabs/Examples-ConnectivityStudio-CSharp .
' Missing some example? Ask us for it on our Online Forums, https://www.opclabs.com/forum/index ! You do not have to own
' a commercial license in order to use Online Forums, and we reply to every post.

Imports OpcLabs.EasySparkplug
Imports OpcLabs.EasySparkplug.OperationModel

Namespace Global.SparkplugDocExamples.Consumer._EasySparkplugConsumer
    Class SubscribeMetric
        Public Shared Sub StateAsInteger()
            ' Note that the default port for the "mqtt" scheme is 1883.
            Dim hostDescriptor = New SparkplugHostDescriptor("mqtt://localhost")

            ' Instantiate the consumer object and hook events.
            Dim consumer = New EasySparkplugConsumer()
            AddHandler consumer.MetricNotification, AddressOf consumer_StateAsInteger_MetricNotification

            Console.WriteLine("Subscribing...")
            consumer.SubscribeMetric(
                New EasySparkplugMetricSubscriptionArguments(SparkplugComponentTypes.EdgeNode, hostDescriptor,
                    "easyGroup", "easySparkplugDemo", "", "Random", Nothing) With
                    {.State = 1}) ' An integer we have chosen to identify the subscription
            consumer.SubscribeMetric(
                New EasySparkplugMetricSubscriptionArguments(SparkplugComponentTypes.EdgeNode, hostDescriptor,
                    "easyGroup", "easySparkplugDemo", "", "Simple", Nothing) With
                    {.State = 2}) ' An integer we have chosen to identify the subscription
            consumer.SubscribeMetric(
                New EasySparkplugMetricSubscriptionArguments(SparkplugComponentTypes.EdgeNode, hostDescriptor,
                    "easyGroup", "easySparkplugDemo", "", "Ramp", Nothing) With
                    {.State = 3}) ' An integer we have chosen to identify the subscription

            Console.WriteLine("Processing notifications for 20 seconds...")
            Threading.Thread.Sleep(20 * 1000)

            Console.WriteLine("Unsubscribing...")
            consumer.UnsubscribeAllMetrics()

            Console.WriteLine("Waiting for 5 seconds...")
            Threading.Thread.Sleep(5 * 1000)

            Console.WriteLine("Finished.")
        End Sub

        Private Shared Sub consumer_StateAsInteger_MetricNotification(ByVal sender As Object, ByVal eventArgs As EasySparkplugMetricNotificationEventArgs)
            ' Obtain the integer state we have passed in.
            ' Note that the metric name also comes with the notification and can be used to determine which metric the
            ' notification relates to. The reason we are using the state is that it allows to pass in the information that
            ' your application understands immediately, and is thus more efficient.
            Dim stateAsInteger = CInt(eventArgs.Arguments.State)

            ' Display the data.
            If (eventArgs.Succeeded) Then
                If (eventArgs.HasData) Then
                    Console.WriteLine($"{stateAsInteger}: {eventArgs.MetricData}")
                End If
            Else
                Console.WriteLine($"{stateAsInteger} *** Failure: {eventArgs.ErrorMessageBrief}")
            End If
        End Sub
    End Class
End Namespace

 

 

Sparkplug is a trademark of Eclipse Foundation, Inc. "MQTT" is a trademark of the OASIS Open standards consortium. Other related terms are trademarks of their respective owners. Any use of these terms on this site is for descriptive purposes only and does not imply any sponsorship, endorsement or affiliation.

See Also